package com.n9.db.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

import java.io.Closeable;
import java.util.Objects;

/**
 * db相关工具
 * @author ice
 */
public class DbUtils {
    private static SessionFactory factory;

    static {
        // 将文件信息加载到内存中
        StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml").build();
        //创建一个配置对象，用于读取配置
        Metadata metadata = new MetadataSources(standardRegistry)
                .getMetadataBuilder()
                .applyImplicitNamingStrategy(
                        ImplicitNamingStrategyJpaCompliantImpl.INSTANCE)
                .build();
        factory = metadata.getSessionFactoryBuilder().build();
    }

    /**
     * 获得数据库连接对象的方法
     * @return
     * @throws Exception
     */
    public static Session openSession() throws DbException{
        try {
            return factory.openSession();
        } catch (Exception e) {
            e.printStackTrace();
            throw new DbException("数据库访问失败..");
        }
    }

    /**
     * 开始事务的方法
     * @throws Exception
     */
    public static void begin(Session session) throws DbException{
        checkSessionIsNotNull(session);

        Transaction transaction = session.beginTransaction();
        if(Objects.nonNull(transaction) && !transaction.isActive()){
            transaction.begin();//开始事务
        }
    }

    /**
     * 提交事务的方法
     * @throws Exception
     */
    public static void commit(Session session)throws DbException {
        checkSessionIsNotNull(session);

        Transaction transaction = session.getTransaction();
        if(transaction!=null){
            transaction.commit();//提交事务
        }
    }

    /**
     * 回滚事务的方法
     */
    public static void rollback(Session session)throws DbException {
        checkSessionIsNotNull(session);

        Transaction transaction = session.getTransaction();
        if(Objects.nonNull(transaction)){
            //回滚事务的方法
            transaction.rollback();
        }
    }

    /**
     * 校验session不能为null
     * @param session
     */
    private static void checkSessionIsNotNull(Session session) throws DbException{
        if (Objects.isNull(session)) {
            throw new DbException("session is null");
        }
    }

    /**
     * 关闭资源
     * @param closeable
     */
    public static void close(Closeable closeable) {
        if (Objects.nonNull(closeable)) {
            try {
                closeable.close();//关掉closeable，释放资源
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 关闭资源
     * @param autoCloseable
     */
    public static void close(AutoCloseable autoCloseable) {
        if (Objects.nonNull(autoCloseable)) {
            try {
                autoCloseable.close();//关掉closeable，释放资源
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
